<?php
/**
 * CounterCacheHabtmBehavior - add counter cache support for HABTM relations
 *
 * Based on CounterCacheBehavior by Derick Ng aka dericknwq
 *
 * @see http://bakery.cakephp.org/articles/view/counter-cache-behavior-for-habtm-relations
 * @author Yuri Pimenov aka Danaki (http://blog.gate.lv)
 * @version 2009-05-28
 */
class AffiliateBehavior extends ModelBehavior
{
    function afterSave(&$model, $created)
    {	
		
        if (Configure::read('affiliate.is_enabled')) {
            $affiliate_model = Cache::read('affiliate_model', 'affiliatetype');
			if(isset($affliate_model)){
            	if (array_key_exists($model->name, $affiliate_model)) {
                		if ($created) {
                    		$this->__createAffiliate($model);
                		} else {
                   		 	$this->__updateAffiliate($model);
                		}
            	}
			}
			else
			{
				$affilate_model = array('');
				if (array_key_exists($model->name, $affiliate_model)) {
                		if ($created) {
                    		$this->__createAffiliate($model);
                		} else {
                   		 	$this->__updateAffiliate($model);
                		}
            	}
			}
        }
    }
    function __createAffiliate(&$model)
    {
        App::import('Core', 'Cookie');
        $collection = new ComponentCollection();
        App::import('Component', 'Email');
        $cookie = new CookieComponent($collection);
        $referrer = $cookie->read('referrer');
        $this->User = $this->__getparentClass('User');
        $affiliate_model = Cache::read('affiliate_model', 'affiliatetype');
        if (((!empty($referrer['refer_id'])) || (!empty($model->data['User']['referred_by_user_id']))) && ($model->name == 'User')) {
            if (empty($referrer['refer_id'])) {
                $referrer['refer_id'] = $model->data['User']['referred_by_user_id'];
            }
            // update refer_id
            $data['User']['referred_by_user_id'] = $referrer['refer_id'];
            $data['User']['id'] = $model->id;
            $this->User->save($data);
            // referred count update
            $this->User->updateAll(array(
                'User.referred_by_user_count' => 'User.referred_by_user_count + ' . '1'
            ) , array(
                'User.id' => $referrer['refer_id']
            ));
            if ($this->__CheckAffiliateUSer($referrer['refer_id'])) {
                $this->AffiliateType = $this->__getparentClass('AffiliateType');
                $affiliateType = $this->AffiliateType->find('first', array(
                    'conditions' => array(
                        'AffiliateType.id' => $affiliate_model['User']
                    ) ,
                    'fields' => array(
                        'AffiliateType.id',
                        'AffiliateType.commission',
                        'AffiliateType.affiliate_commission_type_id'
                    ) ,
                    'recursive' => - 1
                ));
                $affiliate_commision_amount = 0;
                if (!empty($affiliateType)) {
                    if (($affiliateType['AffiliateType']['affiliate_commission_type_id'] == ConstAffiliateCommissionType::Percentage)) {
                        $affiliate_commision_amount = ($model->data['ProjectFund']['commission_amount'] * $affiliateType['AffiliateType']['commission']) / 100;
                        //0.0;
                        
                    } else {
                        $affiliate_commision_amount = $affiliateType['AffiliateType']['commission'];
                    }
                }
                // set affiliate data
                $user_detail = $model->find('first', array('conditions' => array('User.id' => $model->data['User']['id']),  'recursive' => -1));
                $affiliate['Affiliate']['class'] = 'User';
                $affiliate['Affiliate']['foreign_id'] = $model->id;
                $affiliate['Affiliate']['affiliate_type_id'] = $affiliate_model['User'];
                $affiliate['Affiliate']['affliate_user_id'] = $referrer['refer_id'];
                if($user_detail['user']['is_active'])
                {
                  $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::PipeLine;
                }
                else
                {
                  $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::Pending;
                }
                
                $affiliate['Affiliate']['commission_holding_start_date'] = date('Y-m-d');
                $affiliate['Affiliate']['commission_amount'] = $affiliate_commision_amount;
                $this->__saveAffiliate($affiliate);
            }
        } else if ($model->name == 'Project') {
           $this->log('Entered');
            $this->Project = $this->__getparentClass('Project');
            if (empty($referrer['refer_id'])) {
                if (isset($model->data['Project']['user_id']) && !empty($model->data['Project']['user_id'])) {
                   $this->log('Entered into first if');
                    $user = $this->User->find('first', array(
                        'conditions' => array(
                            'User.id' => $model->data['Project']['user_id']
                        ) ,
                        'fields' => array(
                            'User.id',
                            'User.username',
                            'User.referred_by_user_id'
                        ) ,
                        'recursive' => - 1
                    ));
                    if (!empty($user['User']['referred_by_user_id'])) {
                        if (Configure::read('affiliate.commission_on_every_project_listing')) {
                            $referrer['refer_id'] = $user['User']['referred_by_user_id'];
                        } else {
                            $gigorders = $this->Project->find('count', array(
                                'conditions' => array(
                                    'Project.id <>' => $model->id,
                                    'Project.user_id' => $model->data['Project']['user_id'],
                                    'Project.referred_by_user_id' => $user['User']['referred_by_user_id'],
                                ) ,
                            ));
                            if ($gigorders < 1) $referrer['refer_id'] = $user['User']['referred_by_user_id'];
                        }
                    }
                }
            }

            if (!empty($referrer['refer_id']) && $this->__CheckAffiliateUSer($referrer['refer_id'])) {
                $this->AffiliateType = $this->__getparentClass('AffiliateType');
                $affiliateType = $this->AffiliateType->find('first', array(
                    'conditions' => array(
                        'AffiliateType.id' => $affiliate_model['Project']
                    ) ,
                    'fields' => array(
                        'AffiliateType.id',
                        'AffiliateType.commission',
                        'AffiliateType.affiliate_commission_type_id'
                    ) ,
                    'recursive' => - 1
                ));
                $affiliate_commision_amount = 0;
                $admin_commision_amount = 0;
                if (!empty($affiliateType)) {
		        if (Configure::read('Project.project_listing_fee_type') == 'amount') {
		            $total_amount = Configure::read('Project.listing_fee');
		            $this->log('$total_amount starts  if ===='.$total_amount);
				} else {
		            $total_amount = $model->data['Project']['needed_amount'] * (Configure::read('Project.listing_fee') / 100);
				    $total_amount = round($total_amount, 2);
				    $this->log('$total_amount starts else ===='.$total_amount);
		        }

					$model->data['Project']['commission_amount']  = $total_amount;
                    if (($affiliateType['AffiliateType']['affiliate_commission_type_id'] == ConstAffiliateCommissionType::Percentage)) {
                        $affiliate_commision_amount = ($model->data['Project']['commission_amount'] * $affiliateType['AffiliateType']['commission']) / 100;
                        $this->log('$affiliate_commision_amount if ===='.$affiliate_commision_amount);
                    } else {
                        $affiliate_commision_amount = ($model->data['Project']['commission_amount'] - $affiliateType['AffiliateType']['commission']);
                        $this->log('$affiliate_commision_amount else ===='.$affiliate_commision_amount);
                    }
                    $admin_commision_amount = $model->data['Project']['commission_amount'] - $affiliate_commision_amount;
                }
                $this->log('$admin_commision_amount ===='.$admin_commision_amount);
                
                if (!empty($model->data['Project']['project_status_id'])) {
                    $data['Project']['project_status_id'] = $model->data['Project']['project_status_id'];
                }
                $data['Project']['commission_amount'] = $total_amount;
                $data['Project']['referred_by_user_id'] = $referrer['refer_id'];
                $data['Project']['admin_commission_amount'] = $admin_commision_amount;
                $data['Project']['affiliate_commission_amount'] = $affiliate_commision_amount;
                $data['Project']['id'] = $model->id;
				$this->Project->Behaviors->detach('Logable');
                $this->Project->save($data['Project']);
                // set affiliate data
                $affiliate['Affiliate']['class'] = 'Project';
                $affiliate['Affiliate']['foreign_id'] = $model->id;
                $affiliate['Affiliate']['affiliate_type_id'] = $affiliate_model['Project'];
                $affiliate['Affiliate']['affliate_user_id'] = $referrer['refer_id'];
                $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::Pending;
                $affiliate['Affiliate']['commission_amount'] = $affiliate_commision_amount;
                $this->__saveAffiliate($affiliate);
                $this->User->updateAll(array(
                    'User.referred_project_count' => 'User.referred_project_count + ' . '1'
                ) , array(
                    'User.id' => $referrer['refer_id']
                ));
                $conditions['Affiliate.class'] = 'Project';
                $conditions['Affiliate.foreign_id'] = $model->id;
                $affliates = $this->__findAffiliate($conditions);
            }
        }else if ($model->name == 'ProjectFund') {
            $this->ProjectFund = $this->__getparentClass('ProjectFund');
            unset($referrer);
            if (empty($referrer['refer_id'])) {
                if (isset($model->data['ProjectFund']['user_id']) && !empty($model->data['ProjectFund']['user_id'])) {
                    $user = $this->User->find('first', array(
                        'conditions' => array(
                            'User.id' => $model->data['ProjectFund']['user_id']
                        ) ,
                        'fields' => array(
                            'User.id',
                            'User.username',
                            'User.referred_by_user_id'
                        ) ,
                        'recursive' => - 1
                    ));
                   
                    if (!empty($user['User']['referred_by_user_id'])) {
                  
                        if (Configure::read('affiliate.commission_on_every_job_purchase')) {
                            $referrer['refer_id'] = $user['User']['referred_by_user_id'];
                        } else {
                            $gigorders = $this->ProjectFund->find('count', array(
                                'conditions' => array(
                                    'ProjectFund.id <>' => $model->id,
                                    'ProjectFund.user_id' => $model->data['ProjectFund']['user_id'],
                                    'ProjectFund.referred_by_user_id' => $user['User']['referred_by_user_id'],
                                ) ,
                            ));
                            
                            if ($gigorders < 1) $referrer['refer_id'] = $user['User']['referred_by_user_id'];
                        }
                    }
                }
            }
           
            if (!empty($referrer['refer_id']) && $this->__CheckAffiliateUSer($referrer['refer_id'])) {
                $this->AffiliateType = $this->__getparentClass('AffiliateType');
                $affiliateType = $this->AffiliateType->find('first', array(
                    'conditions' => array(
                        'AffiliateType.id' => $affiliate_model['ProjectFund']
                    ) ,
                    'fields' => array(
                        'AffiliateType.id',
                        'AffiliateType.commission',
                        'AffiliateType.affiliate_commission_type_id'
                    ) ,
                    'recursive' => - 1
                ));
				App::import('Model', 'ProjectFund');
				$this->ProjectFund = new ProjectFund();
				$ProjectFund = $this->ProjectFund->find('first', array(
					'conditions' => array(
						'ProjectFund.id' => $model->id,
					),
					'recursive' => -1
				));
                $affiliate_commision_amount = 0;
                $admin_commision_amount = 0;
                if (!empty($affiliateType)) {
                    if (($affiliateType['AffiliateType']['affiliate_commission_type_id'] == ConstAffiliateCommissionType::Percentage)) {
                        $affiliate_commision_amount = ($ProjectFund['ProjectFund']['site_fee'] * $affiliateType['AffiliateType']['commission']) / 100;
                    } else {
                        $affiliate_commision_amount = ($ProjectFund['ProjectFund']['site_fee'] - $affiliateType['AffiliateType']['commission']);
                    }
                    $admin_commision_amount = $ProjectFund['ProjectFund']['site_fee'] - $affiliate_commision_amount;
                }
                $data['ProjectFund']['referred_by_user_id'] = $referrer['refer_id'];
                $data['ProjectFund']['admin_commission_amount'] = $admin_commision_amount;
                $data['ProjectFund']['affiliate_commission_amount'] = $affiliate_commision_amount;
                $data['ProjectFund']['id'] = $model->id;
                $data['ProjectFund']['user_id'] = $model->data['ProjectFund']['user_id'];
                $data['ProjectFund']['project_id'] = $model->data['ProjectFund']['project_id'];
				$this->ProjectFund->Behaviors->detach('Logable');
                $this->ProjectFund->save($data['ProjectFund']);
                // set affiliate data
                $affiliate['Affiliate']['class'] = 'ProjectFund';
                $affiliate['Affiliate']['foreign_id'] = $model->id;
                $affiliate['Affiliate']['affiliate_type_id'] = $affiliate_model['ProjectFund'];
                $affiliate['Affiliate']['affliate_user_id'] = $referrer['refer_id'];
                $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::Pending;
                $affiliate['Affiliate']['commission_amount'] = $affiliate_commision_amount;
                $this->__saveAffiliate($affiliate);
                $this->User->updateAll(array(
                    'User.referred_purchase_count' => 'User.referred_purchase_count + ' . '1'
                ) , array(
                    'User.id' => $referrer['refer_id']
                ));
                $this->User->updateAll(array(
                    'User.affiliate_refer_purchase_count' => 'User.affiliate_refer_purchase_count + ' . '1'
                ) , array(
                    'User.id' => $model->data['ProjectFund']['user_id']
                ));
                $conditions['Affiliate.class'] = 'ProjectFund';
                $conditions['Affiliate.foreign_id'] = $model->id;
                $affliates = $this->__findAffiliate($conditions);
                $this->ProjectFund->Project->updateAll(array(
                    'Project.referred_purchase_count' => 'Project.referred_purchase_count + ' . '1'
                ) , array(
                    'Project.id' => $model->data['ProjectFund']['project_id']
                ));
            }
        }
    }
    function __updateAffiliate(&$model)
    {
        $this->log('Entered in to update');
        if ($model->name == 'ProjectFund') {
            $conditions['Affiliate.class'] = 'ProjectFund';
            $conditions['Affiliate.foreign_id'] = $model->id;
            $affliates = $this->__findAffiliate($conditions);
            $project_fund_detail = $model->find('first', array('conditions' => array('ProjectFund.id' => $model->data['ProjectFund']['id']),  'recursive' => -1));
            if (!empty($project_fund_detail['ProjectFund']['referred_by_user_id'])) {
                $affiliate['Affiliate']['id'] = $affliates['Affiliate']['id'];
                if ($project_fund_detail['ProjectFund']['is_paid'] == 1) {
                    $affiliate['Affiliate']['commission_holding_start_date'] = date('Y-m-d');
                    $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::PipeLine;
                    $this->__saveAffiliate($affiliate);
                } else if ($project_fund_detail['ProjectFund']['is_refunded'] == 1) {
                    $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::Canceled;
                    $this->User = $this->__getparentClass('User');
                    $this->User->updateAll(array(
                        'User.total_commission_canceled_amount' => 'User.total_commission_canceled_amount + ' . $affliates['Affiliate']['commission_amount']
                    ) , array(
                        'User.id' => $affliates['Affiliate']['affliate_user_id']
                    ));
                    $this->__saveAffiliate($affiliate);
                }
                
            }
        }
        elseif ($model->name == 'User') {
            $this->log('Entered in to User update');
            $conditions['Affiliate.class'] = 'User';
            $conditions['Affiliate.foreign_id'] = $model->id;
            $this->log($conditions);
            $affliates = $this->__findAffiliate($conditions);
            // To get project details
            // to get project paid details
            $user_detail = $model->find('first', array('conditions' => array('User.id' => $model->data['User']['id']),  'recursive' => -1));
            $this->log($user_detail);
            $affiliate['Affiliate']['id'] = $affliates['Affiliate']['id'];
            $affiliate['Affiliate']['commission_holding_start_date'] = date('Y-m-d');
                     if ($user_detail['User']['is_active']) {
                        $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::PipeLine;
                    }
                    else
                    {
                        $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::Pending;
                    }
                $this->log('Entered');
                $this->log('Before save'.$affiliate);
                $this->__saveAffiliate($affiliate);
        }
        elseif ($model->name == 'Project') {
            $this->log('Entered in to project update');
            $conditions['Affiliate.class'] = 'Project';
            $conditions['Affiliate.foreign_id'] = $model->id;
            $affliates = $this->__findAffiliate($conditions);
            // To get project details
            // to get project paid details
            $project_detail = $model->find('first', array('conditions' => array('Project.id' => $model->data['Project']['id']),  'recursive' => -1));
            $this->log($project_detail);
            $transaction_detail = $model->Transaction->find('first', array('conditions' => array('Transaction.foreign_id' => $project_detail['Project']['id'], 'Transaction.class' => 'Project'),  'recursive' => -1));
            if (!empty($project_detail['Project']['referred_by_user_id'])) {
                $affiliate['Affiliate']['id'] = $affliates['Affiliate']['id'];
                $this->log($transaction_detail);
                if (!empty($transaction_detail) || !Configure::read('Project.listing_fee')) {
                    $affiliate['Affiliate']['commission_holding_start_date'] = date('Y-m-d');
                    $inactive_statuses = array(ConstProjectStatus::Pending,ConstProjectStatus::ProjectCancelled);
                    if(in_array($project_detail['Project']['project_status_id'],$inactive_statuses))
                    {
                        $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::Pending;
                    }
                    else
                    {
                        $affiliate['Affiliate']['affiliate_status_id'] = ConstAffiliateStatus::PipeLine;
                    }
                }
                $this->log('Entered');
                $this->log('Before save'.$affiliate);
                $this->__saveAffiliate($affiliate);
            }
        }
    }
    function __saveAffiliate($data)
    {
        $this->Affiliate = $this->__getparentClass('Affiliate');
        if (!isset($data['Affiliate']['id'])) {
            $this->Affiliate->create();
            $this->Affiliate->AffiliateUser->updateAll(array(
                'AffiliateUser.total_commission_pending_amount' => 'AffiliateUser.total_commission_pending_amount + ' . $data['Affiliate']['commission_amount']
            ) , array(
                'AffiliateUser.id' => $data['Affiliate']['affliate_user_id']
            ));
        }		
		if (isset($data['Affiliate']['class']) || isset($data['Affiliate']['foreign_id']) || isset($data['Affiliate']['affiliate_status_id']) || isset($data['Affiliate']['commission_amount']) || isset($data['Affiliate']['commission_holding_start_date'])) {
        	$this->Affiliate->save($data);
		}
    }
    function __findAffiliate($condition)
    {
        $this->Affiliate = $this->__getparentClass('Affiliate');
        $affiliate = $this->Affiliate->find('first', array(
            'conditions' => $condition,
            'recursive' => - 1
        ));
        return $affiliate;
    }
    function __CheckAffiliateUSer($refer_user_id)
    {
        $this->User = $this->__getparentClass('User');
        $user = $this->User->find('first', array(
            'conditions' => array(
                'User.id' => $refer_user_id
            ) ,
            'recursive' => - 1
        ));
        if (!empty($user) && ($user['User']['is_affiliate_user'])) {
            return true;
        }
        return false;
    }
    function __getparentClass($parentClass)
    {
        App::import('model', $parentClass);
        return new $parentClass;
    }
}
?>